package com.mc.mcgoweb.utils;


import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.util.StringUtils;

import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.reflect.Method;

public class ModelUtils {

    /**
     * 根据一个实体类获取到对象属性的集合
     *
     * @param object
     * @return
     */
    public static PropertyDescriptor[] getObjProperties(Object object) {
        final BeanWrapper src = new BeanWrapperImpl(object);
        PropertyDescriptor[] pds = src.getPropertyDescriptors();
        return pds;
    }

    /**
     * 根据字段名获取字段get方法
     *
     * @param entityClass
     * @param fieldName
     * @return
     */
    public static Method getReadMethodByFieldName(Class<?> entityClass, String fieldName) {
        if (!StringUtils.isEmpty(fieldName)) {
            BeanWrapperImpl beanWrapper = new BeanWrapperImpl(entityClass);
            return beanWrapper.getPropertyDescriptor(fieldName).getReadMethod();
        } else {
            return null;
        }
    }


    /**
     * 根据getter方法获取setter方法
     *
     * @param entityClass
     * @param getMethod
     * @return
     */
    public static Method getWriteMethodByGetMethod(Class<?> entityClass, Method getMethod) {
        String fieldName = getMethod.getName().substring(3, 4).toLowerCase() + getMethod.getName().substring(4);
        return ModelUtils.getWriteMethodByFieldName(entityClass, fieldName);
    }


    /**
     * 根据setter方法获取getter方法
     *
     * @param entityClass
     * @param setMethod
     * @return
     */
    public static Method getReadMethodBySetMethod(Class<?> entityClass, Method setMethod) {
        String fieldName = setMethod.getName().substring(3, 4).toLowerCase() + setMethod.getName().substring(4);
        return ModelUtils.getReadMethodByFieldName(entityClass, fieldName);
    }

    /**
     * 根据字段名获取字段set方法
     *
     * @param entityClass
     * @param fieldName
     * @return
     */
    public static Method getWriteMethodByFieldName(Class<?> entityClass, String fieldName) {
        if (!StringUtils.isEmpty(fieldName)) {
            BeanWrapperImpl beanWrapper = new BeanWrapperImpl(entityClass);
            return beanWrapper.getPropertyDescriptor(fieldName).getWriteMethod();
        } else {
            return null;
        }
    }

    /**
     * 根据字段名获取字段值
     *
     * @param obj
     * @param fieldName
     * @return
     */
    public static Serializable getFieldValueByFieldName(Object obj, String fieldName) {
        if (!StringUtils.isEmpty(fieldName)) {
            return (Serializable) new BeanWrapperImpl(obj).getPropertyValue(fieldName);
        } else {
            return null;
        }
    }


    /**
     * 将驼峰式命名的字符串转换为下划线大写方式。如果转换前的驼峰式命名的字符串为空，则返回空字符串。</br> 例如：HelloWorld->HELLO_WORLD
     *
     * @param name 转换前的驼峰式命名的字符串
     * @return 转换后下划线大写方式命名的字符串
     */
    public static String underscoreName(String name) {
        StringBuilder result = new StringBuilder();
        if (name != null && name.length() > 0) {
            // 将第一个字符处理成大写
            result.append(name.substring(0, 1).toUpperCase());
            // 循环处理其余字符
            for (int i = 1; i < name.length(); i++) {
                String s = name.substring(i, i + 1);
                // 在大写字母前添加下划线
                if (s.equals(s.toUpperCase()) && !Character.isDigit(s.charAt(0))) {
                    result.append("_");
                }
                // 其他字符直接转成大写
                result.append(s.toUpperCase());
            }
        }
        return result.toString();
    }

    /**
     * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空，则返回空字符串。</br> 例如：HELLO_WORLD->HelloWorld
     *
     * @param name 转换前的下划线大写方式命名的字符串
     * @return 转换后的驼峰式命名的字符串
     */
    public static String camelName(String name) {
        StringBuilder result = new StringBuilder();
        // 快速检查
        if (name == null || StringUtils.isEmpty(name)) {
            // 没必要转换
            return "";
        } else if (!name.contains("_")) {
            // 不含下划线，仅将首字母小写
            return name.substring(0, 1).toLowerCase() + name.substring(1);
        }
        // 用下划线将原始字符串分割
        String camels[] = name.split("_");
        for (String camel : camels) {
            // 跳过原始字符串中开头、结尾的下换线或双重下划线
            if (StringUtils.isEmpty(camel)) {
                continue;
            }
            // 处理真正的驼峰片段
            if (result.length() == 0) {
                // 第一个驼峰片段，全部字母都小写
                result.append(camel.toLowerCase());
            } else {
                // 其他的驼峰片段，首字母大写
                result.append(camel.substring(0, 1).toUpperCase());
                result.append(camel.substring(1).toLowerCase());
            }
        }
        return result.toString();
    }

}
